/*
 * Project: com.mmall.common.spring.security.impl
 *
 * File Created at 2019-10-20
 *
 * Copyright 2019 CMCC Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * ZYHY Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license.
 */
package com.mmall.common.spring.security.impl;

import com.common.framework.bo.TokenBO;
import com.common.framework.dto.TokenDTO;
import com.common.framework.exception.AuthorizedException;
import com.common.framework.util.DateUtil;
import com.mmall.common.spring.config.PropertiesConfig;
import com.mmall.common.spring.security.AuthHelper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.validation.constraints.NotNull;
import javax.xml.bind.DatatypeConverter;
import java.util.Date;

/**
 * @author jianghucoding
 * @date 2019-10-20
 */
@Component
public class JWTAuthHelperImpl implements AuthHelper {

    @Autowired
    private PropertiesConfig propertiesConfig;

    @Override
    public TokenBO generateToken(TokenDTO tokenDTO) {
        Date currentDate = new Date();
        String jws = Jwts.builder()
            .setIssuedAt(currentDate)
            .setIssuer(String.valueOf(tokenDTO.getUserId()))
            .setExpiration(DateUtil.addHour(currentDate, propertiesConfig.getTokenValidPeriodHour()))
            .signWith(SignatureAlgorithm.HS512, DatatypeConverter.parseBase64Binary(propertiesConfig.getTokenSecret()))
            .compact();
        return TokenBO.builder().token(jws).build();
    }

    @Override
    public TokenDTO analysisToken(@NotNull String token) {
        try {
            Claims jwtClaims = Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(propertiesConfig.getTokenSecret()))
                .parseClaimsJws(token).getBody();
            return TokenDTO.builder().userId(Long.valueOf(jwtClaims.getIssuer())).build();
        } catch (Exception e) {
            e.printStackTrace();
            // token 过期或者是 token 字符串非法
            throw new AuthorizedException();
        }
    }
}
